unit Pendulum;

interface

	uses
	  SysUtils, Classes;

	type
		
		TPendulum = Class(TObject)
		Private
			//Physical properties
			_stringLength : real;
			_bobMass : real;
			_bobDiameter : real;
			
			
		Public
			Property StringLength : Real Read _stringLength Write _stringLength;
			Property BobMass : Real Read _bobMass Write _bobMass;
			Property BobDiameter : Real Read _bobDiameter Write _bobDiameter;
			
			Constructor Create (StringLength, BobMass, BobDiameter : Real);
			Function CalculateInclination(PrevInclination, PrevAngularVelocity, TimeStep: Real) : Real; virtual;
			Function CalculateAngularVelocity( PrevAngularVelocity, CurrentInclination, TimeStep, Gravity: Real) : Real; virtual;
			Function CalculateAngularVelocityWithDamping( PrevAngularVelocity, CurrentInclination, PrevInclination, DampingFactor, TimeStep, Gravity: Real) : Real; virtual;
		end;
	
implementation
	
	Constructor TPendulum.Create (StringLength, BobMass, BobDiameter : Real);
	begin
		_stringLength := StringLength;
		_bobMass := BobMass;
		_bobDiameter := BobDiameter;
	end;
	
	Function TPendulum.CalculateInclination(PrevInclination, PrevAngularVelocity, TimeStep: Real) : Real;
	begin
		CalculateInclination := PrevInclination + PrevAngularVelocity*TimeStep;
	end;

	Function TPendulum.CalculateAngularVelocity( PrevAngularVelocity, CurrentInclination, TimeStep, Gravity: Real) : Real;
	begin
		CalculateAngularVelocity :=  PrevAngularVelocity  - (Gravity/self.StringLength)*Sin(CurrentInclination)*TimeStep;
	end;
	
	Function TPendulum.CalculateAngularVelocityWithDamping( PrevAngularVelocity, CurrentInclination, PrevInclination, DampingFactor ,TimeStep, Gravity: Real) : Real;
	var
		undampedAV : Real;
	begin
		//Damped AV is the same as the previous AV but with a correction of -2*sqrt(g/l)*dampFactor*(thetaValues(i) - thetaValues(i-1))
		undampedAV := CalculateAngularVelocity(PrevAngularVelocity, CurrentInclination, TimeStep, Gravity);
		CalculateAngularVelocityWithDamping := undampedAV - 2*sqrt(Gravity/StringLength)*DampingFactor*(CurrentInclination - PrevInclination);
		
	end;
end.
